package controllers

import (
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego"
	"neecola.com/learngo/family_security/models"
	"regexp"
	"time"
)

// 管理员
// 功能表
// 修改用户信息以及和用户通信硬件的信息
// 管理员可以添加上位机控制硬件终端以及硬件终端的子终端的信息
// 管理原修改完成信息后, 后即时更新缓存上的数据, 比如和用户有关的信息
//*************************************************************
// 及时修改myUserInfoRedis 上对应的数据
// 向app 端推送更新硬件终端的数据
// 保存对应的数据
//*************************************************************
// 管理员登录.....
type AdminCtr struct {
	beego.Controller
}

const (
	su_login = "/admin/login"
	admin_op = "/admin/op"
)

// 请求登录页面...
// 如果管理员已经登录了, 重定向到管理员的页面...
//
func (this *AdminCtr) Login() {

	admin := this.GetSession("admin")
	// 如果管理员已经登录, 重定向到用户的管理页面
	if admin != nil {
		this.Redirect(admin_op, 302)
		return
	}
	this.TplName = "admin/login.html"
}

// post commit admin info
func (this *AdminCtr) LoginP() {
	admin := this.GetString("admin") // 获取管理员的用户名
	passwd := this.GetString("passwd")
	// 重定向到登录页面
	if admin == "" || passwd == "" {
		this.Redirect(su_login, 302)
		return
	}

	// 查找管理员的信息 ... 匹配 pass
	su := &models.Admin{}
	//伪初始化 用户信息
	su.Name = admin
	su.Passwd = passwd

	fmt.Println("su ", su)
	err := su.Read("name", "passwd")

	fmt.Println("error ", err)
	if err != nil {
		//用户的信息不正确
		this.Redirect(su_login, 302)
		return
	}

	fmt.Println("ok pass ", su)
	this.SetSession("admin", su)
	// 转到管理员的管理页面
	this.Redirect(admin_op, 302)
	return
}

func (this *AdminCtr) ViewTotal() {
	admin := this.GetSession("admin")
	if admin == nil {
		this.Redirect(su_login, 302)
		return
	}

	this.Data["admin"] = admin
	this.Data["map"] = myUserInfoRedis
	this.TplName = "admin/totalView.html"
	return
}

func (this *AdminCtr) FetchData() {
	admin := this.GetSession("admin")

	if admin == nil {
		this.Redirect(su_login, 302)
		fmt.Println("su but not login bye bye")
		return
	}
}

// 增加子结点
// get
func (this *AdminCtr) AddSubMac() {

}

// 为结点添加新的子结点
// 获取mac 地址和子结点的信息
// 及时修改myUserInfoRedis
func (this *AdminCtr) AddSubMacP() {

	// 如果用户没有登录,
	// 定向到用户的登录页面
	if admin := this.GetSession("admin"); admin == nil {
		this.Redirect(su_login, 302)
		return
	}

	req := struct {
		Phone    string `json:"phone"`
		Location string `json:"location"`
		Mac      string `json:"mac"`
	}{}

	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
		fmt.Printf("error ", err)
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: "error",
		}
		this.ServeJSON(true)
		return
	}

	// 正则校验手机号码
	if ok, _ := regexp.MatchString(`^(1[3|4|5|8][0-9]\d{4,8})$`, req.Phone); !ok {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `手机号码不正确`,
		}
		this.ServeJSON(true)
		return
	}

	// 校验mac 地址
	if ok, _ := regexp.MatchString(`[A-Fa-f0-9]{16}`, req.Mac); !ok {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `mac地址不正确`,
		}
		this.ServeJSON(true)
		return
	}
	var info *models.UserInfo = nil
	info, ok := myUserInfoRedis[req.Phone]
	if !ok {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `送你98k哟`,
		}
		this.ServeJSON(true)
		return
	}
	if info == nil {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `送你98k哟`,
		}
		this.ServeJSON(true)
		return
	}
	sub := models.SubMac{}

	sub.Mac = req.Mac
	sub.Location = req.Location
	sub.UserInfo = info

	_, err := sub.Insert()

	if err != nil {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `get some error `,
		}
		this.ServeJSON(true)
		return
	}

	info.SubMac = append(info.SubMac, &sub)

	// 需要向用户推送一个添加新节点的消息
	message := ProxyMessage{}
	message.Phone = req.Phone
	message.Code = 1024

	sm := struct {
		Mac      string `json:"mac"`
		PMac     string `json:"pMac"`
		Location string `json:"location"`
	}{}
	sm.Location = req.Location
	sm.Mac = req.Mac
	sm.PMac = info.Mac
	bs, _ := json.Marshal(sm)

	message.Msg = string(bs)

	chAddSubMac <- message

	this.Data["json"] = struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}{
		Code:    200,
		Message: "o98k",
	}
	this.ServeJSON(true)
	return
}

// 添加新的硬件信息
// get
// 判断管理原是否已经登录了
//
func (this *AdminCtr) AddMac() {

}

// 添加新的终端
// post
// 获取 用户的手机号码
// 硬件的mac地址
// 及时修改myUserInfoRedis
func (this *AdminCtr) AddMacP() {

	// 如果用户没有登录,
	// 定向到用户的登录页面
	if admin := this.GetSession("admin"); admin == nil {
		this.Redirect(su_login, 302)
		return
	}
	req := struct {
		Phone  string `json:"phone"`
		Passwd string `json:"passwd"`
		Mac    string `json:"mac"`
	}{}

	if err := json.Unmarshal(this.Ctx.Input.RequestBody, &req); err != nil {
		fmt.Printf("error ", err)
		this.Data["json"] = struct {
			Code int `json:"code"`
		}{
			Code: 400,
		}
		this.ServeJSON(true)
		return
	}

	fmt.Printf("req =%+v \n", req)
	// 密码的长度不能小于8
	if len(req.Passwd) < 8 {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `密码的长度不正确`,
		}
		this.ServeJSON(true)
		return
	}

	// 正则校验手机号码
	if ok, _ := regexp.MatchString(`^(1[3|4|5|8][0-9]\d{4,8})$`, req.Phone); !ok {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `手机号码不正确`,
		}
		this.ServeJSON(true)
		return
	}

	// 校验mac 地址
	if ok, _ := regexp.MatchString(`[A-Fa-f0-9]{16}`, req.Mac); !ok {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `mac地址不正确`,
		}
		this.ServeJSON(true)
		return
	}

	// 判断改mac 是否可以使用
	if info := getUserInfoByMac(req.Mac); info != nil {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `改mac地址已经被使用了`,
		}
		this.ServeJSON(true)
		return
	}
	// 判断  手机号码 | mac 是否已经被使用了
	if _, ok := myUserInfoRedis[req.Phone]; ok {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `该手机号码不可使用`,
		}
		this.ServeJSON(true)
		return
	}

	// 更新 myUserInfoRedis
	// 将数据插入数据库
	info := models.UserInfo{}
	info.Mac = req.Mac
	info.Phone = req.Phone
	info.PassWord = req.Passwd
	info.RegisterTime = time.Now()
	_, err := info.Insert()
	if err != nil {
		this.Data["json"] = struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
		}{
			Code:    400,
			Message: `未知错误`,
		}

		this.ServeJSON(true)
		return
	}

	// 更新myUserInfoRedis
	myUserInfoRedis[info.Phone] = &info

	this.Data["json"] = struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
	}{
		Code:    200,
		Message: "o98k",
	}
	this.ServeJSON(true)
	return

}

// 管理员退出登录
func (this *AdminCtr) Exit() {
	this.DelSession("admin")
	this.Redirect(su_login, 302)
	return
}
